package com.java.comprehensive.thread.forkjoin;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * @program: comprehensive-service
 *
 * @description:
 *
 * @author: 窦绍飞
 *
 * @create: 2022-01-26 10:08
 **/
public class Demo02 {

    public static final Integer MIN_CUT = 500;

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();
        System.out.println("核心数：" + Runtime.getRuntime().availableProcessors());
        ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors());
        List<Integer> list = new ArrayList<>();
        for (int i = 1; i <= 2000; i++) {
            list.add(i);
        }

        ForkJoinTask<Integer> submit = forkJoinPool.submit(new AddTaskReturn(list));
        long end = System.currentTimeMillis();
        System.out.println(submit.get());
        System.out.println("总耗时：" + (end - start));

    }

    static class AddTaskReturn extends RecursiveTask<Integer> {

        public List<Integer> numList;


        public AddTaskReturn(List<Integer> numList) {
            this.numList = numList;
        }

        @Override
        protected Integer compute() {
            if (numList.size() < MIN_CUT) {
                //一次性能最低处理多少个数据
                System.out.println("direct calc" + numList.size());
                return directCalc();
            }
            int size = numList.size();
            AddTaskReturn task1 = new AddTaskReturn(numList.subList(0, size / 2));
            AddTaskReturn task2 = new AddTaskReturn(numList.subList(size / 2, size));
            invokeAll(task1, task2);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return task1.join() + task2.join();
        }

        public Integer directCalc() {
            return numList.stream().reduce(Integer::sum).orElse(0);
        }
    }
}
